
#pragma once

#include "define.h"
#include "loop_event.hpp"
#include "stun_message.h"
#include "turn_client_main/peer_client_process.h"
#include "udp_client.h"
#include <cstdint>
#include <cstring>
#include <memory>
#include <netinet/in.h>
#include <string>
#include <unistd.h>
#include <arpa/inet.h>
#include "file_operation.h"

struct AllocateDataInformation
{
    bool m_allocate_success{false};
    std::string m_nonce_id;
    std::string m_realm;

    int m_lifetime;
    struct sockaddr_in m_relay_sai;
    std::string m_relay_addr;
    uint16_t    m_relay_port;
    FileOperation m_file_operation;
};

void SendMessage(LoopEvent * loop_event, UdpClient * client, StunMessage & message);

void AllocateRequest(LoopEvent * loop_event, UdpClient * client, StunMessage & message);

void SendTestData(LoopEvent * loop_event, UdpClient * client, AllocateDataInformation & information, PeerClientInformation & peer_information);

void SendRefreshRequest(LoopEvent * loop_event, UdpClient * client, AllocateDataInformation & information);

void AddPermission(LoopEvent * loop_event, UdpClient * client, AllocateDataInformation & information, PeerClientInformation & peer_information);

void ProcessBindResponse(LoopEvent * loop_event, UdpClient * client, StunMessage & message);

void ProcessAllocateErrorResponse(LoopEvent * loop_event, UdpClient * client, StunMessage & message, AllocateDataInformation & information);

void ProcessAllocateSuccessResponse(
    LoopEvent * loop_event, 
    UdpClient * client, 
    StunMessage & message, 
    AllocateDataInformation & information, 
    PeerClientInformation & peer_information);


void AddPermissionSuccessResponse(LoopEvent * loop_event, UdpClient * client, StunMessage & message, AllocateDataInformation & information, PeerClientInformation & peer_information);


void ProcessDataIndication(
        LoopEvent * loop_event, UdpClient * client, StunMessage & message, 
        AllocateDataInformation & information, PeerClientInformation & peer_information);

void SendFileContent(LoopEvent * loop_event, UdpClient * client, AllocateDataInformation & information, PeerClientInformation & peer_information);
